package com.authine.cloudpivot.ext.applicationservice.organization;

import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.dto.kingDee.KingDeeBusiness;
import com.authine.cloudpivot.ext.dto.kingDee.request.KingDeeMember;
import com.authine.cloudpivot.ext.dto.system.DepartmentDto;
import com.authine.cloudpivot.ext.enums.kingdee.BusinessType;
import com.authine.cloudpivot.ext.service.OrganizationDataService;
import com.authine.cloudpivot.ext.utils.BoServiceUtils;
import com.authine.cloudpivot.ext.utils.JdbcTemplateUtils;
import com.authine.cloudpivot.ext.utils.system.BeanUtils;
import com.authine.common.util.ObjectMapperUtils;
import com.authine.hermes.app.launcher.org.v2.DepartmentV2;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * @ClassName DepartmentApi
 * @Description: 部门api接口
 * @Author fj
 * @Date 2021/7/2
 * @Version V1.0
 **/
@Path("DepartmentApi")
@Slf4j
public class DepartmentApi extends ApplicationService {
    public static final UserApi userApi = new UserApi();
    public static final OrganizationDataService organizationDataService = new OrganizationDataService();

    /**
     * 根据查询条件获取用户是否存在
     *
     * @param param 查询条件
     * @return 查询结果总数
     */
    public Integer deptCount(Map<String, Object> param) {
        // 获取请求参数key
        String key = param.keySet().iterator().next();
        List<Map<String, Object>> deptList = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_DEPARTMENT).selectField("id, organization_id, manager_user_id, organization_name, manager_name, " +
                "number, name, description, version"))
                .eq(key, param.get(key))
                .queryForList();
        log.info("------------------------查询部门列表返回结果：{}------------------------", JSONObject.toJSONString(deptList));
        return deptList.size();
    }

    /**
     * 保存部门信息
     *
     * @param department 部门信息
     */
    @Path("saveDept")
    @POST
    @Operation(summary = "保存部门信息", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> saveDept(@Parameter DepartmentDto department) {
        // 判断组织信息是否存在
        if (CollectionUtils.isEmpty(department.getOrganization_id())) {
            return SingleResponse.error("-1", "创建部门时，组织不能为空");
        }
        // 判断部门经理是否存在
        Map<String, Object> param = Maps.newHashMap();
        if (!CollectionUtils.isEmpty(department.getManager_user_id())) {
            param.put("id", department.getManager_user_id().get(0).getId());
            int count = userApi.userCount(param);
            if (count == 0) {
                return SingleResponse.error("-2", "部门经理用户不存在");
            }
        }

        setDeptValue(department);

        // 创建云枢部门
        DepartmentV2 departmentV2 = buildDepartmentV2(department);
        log.info("------------------------新增云枢部门参数：{}------------------------", JSONObject.toJSONString(departmentV2));

        SingleResponse<DepartmentV2> departmentResponse = this.orgServiceV2.createDepartment(departmentV2);

        if (!departmentResponse.isSuccess()) {
            return SingleResponse.error(departmentResponse.getErrCode(), departmentResponse.getErrMessage());
        }
        log.info("------------------------云枢部门数据新增成功,部门信息：{}------------------------", JSONObject.toJSONString(departmentResponse.getData()));
        // 保存部门信息到系统管理中，id和云枢部门id保持同步
        department.setId(departmentResponse.getData().getId());

        Map<String, Object> departmentMap = BeanUtils.bean2Map(department);

        log.info("------------------------创建系统管理部门参数：{}------------------------", JSONObject.toJSONString(departmentMap));
        SingleResponse<BO> createDepartmentBO = BoServiceUtils.createBo(ModelConst.T_DEPARTMENT, Collections.singletonList(departmentMap));
        if (!createDepartmentBO.isSuccess()) {
            return SingleResponse.error("-4", "系统管理部门创建失败");
        }
        log.info("------------------------系统管理部门数据新增成功，部门信息：{}------------------------", JSONObject.toJSONString(createDepartmentBO));
        // 保存信息到金蝶中
        KingDeeBusiness kingDeeBusiness = KingDeeBusiness.builder()
                .businessId(createDepartmentBO.getData().getBizObjectId())
                .businessType(BusinessType.Department)
                .build();
        KingDeeMember kingDeeMember = KingDeeMember.builder()
                .number(createDepartmentBO.getData().getBizObjectId())
                .name(String.valueOf(createDepartmentBO.getData().getData().get("name")))
                .business(kingDeeBusiness)
                .build();
        organizationDataService.createDepartment(kingDeeMember);
        return createDepartmentBO;
    }

    /**
     * 更新部门信息
     *
     * @param department 部门信息
     */
    @Path("updateDept")
    @POST
    @Operation(summary = "更新部门信息", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateDept(@Parameter DepartmentDto department) {
        Assert.notNull(department.getId(), "ID不能为空");
        Map<String, Object> param = Maps.newHashMap();
        param.put("id", department.getId());
        int deptCount = this.deptCount(param);
        if (deptCount == 0) {
            return SingleResponse.error("-1", "ID:" + department.getId() + "不存在");
        }
        if (CollectionUtils.isEmpty(department.getOrganization_id())) {
            return SingleResponse.error("-2", "组织不能为空");
        }

        setDeptValue(department);

        // 获取修改之前的部门信息
        DepartmentDto oldDepartment = this.getDeptByIdThroughJDBC(department);
        log.info("------------------------修改之前的部门数据map转为javaBean：{}------------------------", JSONObject.toJSONString(oldDepartment));
        if (!department.getName().equals(oldDepartment.getName()) || !department.getOrganization_name().equals(oldDepartment.getOrganization_name())) {
            // 修改云枢部门
            DepartmentV2 departmentV2 = buildDepartmentV2(department);
            SingleResponse<DepartmentV2> departmentResponse = this.orgServiceV2.updateDepartment(departmentV2);
            if (!departmentResponse.isSuccess()) {
                return SingleResponse.error(departmentResponse.getErrCode(), departmentResponse.getErrMessage());
            }
        }
        // 修改系统管理部门
        Map<String, Object> departmentMap = BeanUtils.bean2Map(department);
        log.info("------------------------修改系统管理部门参数：{}------------------------", JSONObject.toJSONString(departmentMap));
        SingleResponse<BO> updateDepartmentBO = BoServiceUtils.updateMainBo(ModelConst.T_DEPARTMENT, departmentMap);
        if (!updateDepartmentBO.isSuccess()) {
            return SingleResponse.error("-4", "系统管理部门修改失败");
        }
        // 修改部门名称后，同步修改用户中的部门名称
        if (!oldDepartment.getName().equals(department.getName())) {
            SelectorFormat deptSelectorFormat = new SelectorFormat();
            deptSelectorFormat.setType(1);
            deptSelectorFormat.setId(department.getId());
            deptSelectorFormat.setName(department.getName());
            // 获取需要修改的用户
            List<Map<String, Object>> userListData = Lists.newArrayList();
            SingleResponse<BOList> userBOList = userApi.getUsersByDeptName(oldDepartment.getName());
            userBOList.getData().getData().forEach(map -> {
                Map<String, Object> userMap = Maps.newHashMap();
                userMap.put("id", map.get("id"));
                userMap.put("department_id", deptSelectorFormat);
                userMap.put("department_name", deptSelectorFormat.getName());
                userListData.add(userMap);
            });
            log.info("------------------------当前部门下需要修改的用户信息：{}------------------------", JSONObject.toJSONString(userListData));
            if (userListData.size() > 0) {
                SingleResponse<BO> updateUserBO = BoServiceUtils.updateMainBo(ModelConst.T_USER, userListData);
                if (!updateUserBO.isSuccess()) {
                    return SingleResponse.error("-5", "系统管理修改部门下用户信息失败");
                }
            }
        }
        return updateDepartmentBO;
    }

    /**
     * 根据部门id获取部门信息
     *
     * @param param 部门信息
     * @return 响应结果
     */
    @Path("getDept")
    @POST
    @Operation(summary = "根据部门id获取部门信息", tags = CUSTOM_SERVICE)
    public DepartmentDto getDept(@Parameter DepartmentDto param) {
        Assert.notNull(param.getId(), "ID不能为空");
        SingleResponse<BOList> deptBO = BoServiceUtils.findListBySimple(ModelConst.T_DEPARTMENT, "id", param.getId());
        if (deptBO.getData().getTotal() == 0) {
            throw new BizException("部门ID:" + param.getId() + "不存在");
        }
        DepartmentDto departmentDto = ObjectMapperUtils.fromJSON(JSONObject.toJSONString(deptBO.getData().getData().get(0)), DepartmentDto.class);
        log.info("------------------------根据部门id获取部门信息返回结果：{}------------------------", JSONObject.toJSONString(departmentDto));
        return departmentDto;
    }

    /**
     * 使用jdbc查询的方式获取部门信息
     *
     * @param param 部门信息
     * @return 响应结果
     */
    @Path("getDeptByIdThroughJDBC")
    @POST
    @Operation(summary = "使用jdbc查询的方式获取部门信息", tags = CUSTOM_SERVICE)
    public DepartmentDto getDeptByIdThroughJDBC(@Parameter DepartmentDto param) {
        Assert.notNull(param.getId(), "ID不能为空");
        DepartmentDto dept = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_DEPARTMENT).selectField("id, organization_id, manager_user_id, organization_name, manager_name, " +
                "number, name, description, version"))
                .eq("id", param.getId())
                .queryForPOJO(DepartmentDto.class, true);
        if (dept == null) {
            throw new BizException("部门ID:" + param.getId() + "不存在");
        }
        log.info("------------------------通过jdbc查询，根据部门id获取部门信息返回结果：{}------------------------", JSONObject.toJSONString(dept));
        return dept;
    }

    /**
     * 获取组织下所有部门信息
     *
     * @param orgName 组织名称
     * @return 部门列表
     */
    public SingleResponse<BOList> getDepartmentsByOrgName(String orgName) {
        Assert.notNull(orgName, "组织名称不能为空");
        SingleResponse<BOList> departmentBOList = BoServiceUtils.findListBySimple(ModelConst.T_DEPARTMENT, "organization_name", orgName);
        log.info("------------------------根据组织名称获取到的部门信息：{}------------------------", JSONObject.toJSONString(departmentBOList));
        return departmentBOList;
    }

    /**
     * 构建云枢部门对象
     *
     * @param department 部门信息
     * @return 结果
     */
    private DepartmentV2 buildDepartmentV2(DepartmentDto department) {
        DepartmentV2 departmentV2 = new DepartmentV2();
        if (!StringUtils.isEmpty(department.getId())) {
            departmentV2.setId(department.getId());
        }
        departmentV2.setName(department.getName());
        departmentV2.setParentId(department.getOrganization_id().get(0).getId());
        // 部门主管
        if (!CollectionUtils.isEmpty(department.getManager_user_id())) {
            departmentV2.setManagerId(department.getManager_user_id().get(0).getId());
        }
        return departmentV2;
    }

    /**
     * 设置部门选人控件冗余名称
     *
     * @param department 部门信息
     */
    private void setDeptValue(DepartmentDto department) {
        if (!CollectionUtils.isEmpty(department.getOrganization_id())) {
            department.setOrganization_name(department.getOrganization_id().get(0).getName());
        } else {
            department.setOrganization_name("");
            department.setOrganization_id(null);
        }
        if (!CollectionUtils.isEmpty(department.getManager_user_id())) {
            department.setManager_name(department.getManager_user_id().get(0).getName());
        } else {
            department.setManager_name("");
            department.setManager_user_id(null);
        }
    }
}
